#ifndef MODEL_H
#define MODEL_H

#include <GL/glut.h>
#include <GL/glu.h>
#include "algebra3.h"
#include <vector>



class Face{
public:
	vec3 v1, v2, v3;
	
	Face(vec3 a, vec3 b, vec3 c){
		v1 = a;
		v2 = b;
		v3 = c;
	}
	
	void print(){
		cout << v1 << v2 << v3 << endl;
	}
};

class Material{
public:
	vec3 kd, ka, ks, transparent;
	int illum, shiny, refract;
	
	void shading(){
		GLfloat diffuse[] = {kd[0], kd[1], kd[2]};
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
		
		GLfloat spec[] = {ks[0], ks[1], ks[2]};
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
		
		GLfloat sp[] = {shiny};
		glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, sp);
		
		GLfloat ambient[] = {ka[0], ka[1], ka[2]};
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
		
		//glEnable(GL_BLEND);
		glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
	}
};

class BoundingBox{
public:
	vec3 aabb[8];
	
    BoundingBox() { }


	BoundingBox(vec3 v1,vec3 v2,vec3 v3,vec3 v4,vec3 v5,vec3 v6,vec3 v7,vec3 v8){
        aabb[0] = v1;
        aabb[1] = v2;
        aabb[2] = v3;
        aabb[3] = v4;
        aabb[4] = v5;
        aabb[5] = v6;
        aabb[6] = v7;
        aabb[7] = v8;
	}

    BoundingBox(vec3 min, vec3 max){
        aabb[0] = min;
        aabb[1] = vec3(max[0],min[1],min[2]);
        aabb[2] = vec3(max[0],max[1],min[2]);
        aabb[3] = vec3(min[0],max[1],max[2]);
        aabb[4] = vec3(min[0],min[1],max[2]);
        aabb[5] = vec3(max[0],min[1],max[2]);
        aabb[6] = max;
        aabb[7] = vec3(min[0],max[1],max[2]);
        }
	
	void translate(vec3 transVector){
        for(int i=0;i<8;i++){
            aabb[i] = aabb[i] + transVector;
            }
        }

};

class Model{
public:
	vector<vec3> points, normals;
	vector<vec2> textures;
	vector<Face> faces;
	Material mat;
	BoundingBox box;
	int count;
	
	Model(){
		vector<vec3> points, normals;
		vector<vec2> textures;
		vector<Face> faces;
		BoundingBox box;
		count = 0;
	}
	
	void draw(){
		mat.shading();
		
		glBegin(GL_TRIANGLES);
		
		int vert, text, norm;
		for (int i = 0; i < count; i++){
			vert = faces[i].v1[0] -1;
			text = faces[i].v1[1] -1;
			norm = faces[i].v1[2] -1;
			
			glTexCoord2f(textures[text][0], textures[text][1]);
			glNormal3f(normals[norm][0], normals[norm][1], normals[norm][2]);
			glVertex3f(points[vert][0], points[vert][1], points[vert][2]);
			
			vert = faces[i].v2[0] -1;
			text = faces[i].v2[1] -1;
			norm = faces[i].v2[2] -1;
			
			glTexCoord2f(textures[text][0], textures[text][1]);
			glNormal3f(normals[norm][0], normals[norm][1], normals[norm][2]);
			glVertex3f(points[vert][0], points[vert][1], points[vert][2]);
			
			vert = faces[i].v3[0] -1;
			text = faces[i].v3[1] -1;
			norm = faces[i].v3[2] -1;
			
			glTexCoord2f(textures[text][0], textures[text][1]);
			glNormal3f(normals[norm][0], normals[norm][1], normals[norm][2]);
			glVertex3f(points[vert][0], points[vert][1], points[vert][2]);
		}
		
		glEnd();
		//glDisable(GL_BLEND);
	}

    void drawBB(){
        glDisable(GL_LIGHTING);
		glBegin(GL_POINTS);
            for(int i=0;i<8;i++){
			glVertex3f(box.aabb[i][0],box.aabb[i][1],box.aabb[i][2]);
                }
		glEnd();
		glEnable(GL_LIGHTING);
	}
	
	void print(){
		cout << "Count: " << count <<endl;
		for (int i = 0; i < count; i++){
			cout << "=== Face " << i << " ==="<< endl;
			//faces[i].print();
			
			cout << "==== Vertices ==== "<< endl;
			cout << points[faces[i].v1[0] -1] << endl;
			cout << points[faces[i].v2[0] -1] << endl;
			cout << points[faces[i].v3[0] -1] << endl;
			
			cout << "==== Normals ==== "<< endl;
			cout << normals[faces[i].v1[0] -1] << endl;
			cout << normals[faces[i].v2[0] -1] << endl;
			cout << normals[faces[i].v3[0] -1] << endl;
		}
	}
	
};

#endif